﻿using System;

namespace paiban.data
{
    using xlstool;
    public class WorkTableThumb // 缩略
    {
        internal int[] thumb;
        internal int[] thumb_sum;
        internal int[] thumb_repeat;
        internal int thumb_count;
        internal int thumb_sum_count;
        internal int thumb_repeat_count;
        internal WorkTable table { get; set; }
        public WorkTableThumb(WorkTable table)
        {
            this.table = table;
            thumb_count = table.info.work_person_count * table.work_count;
            thumb_sum_count = table.info.work_person_count;
            thumb_repeat_count = (table.work_count * (table.work_count -1)) >> 1; // 1+ 2+ 3+ n
            thumb = new int[thumb_count];
            thumb_sum = new int[thumb_sum_count];
            thumb_repeat = new int[thumb_repeat_count];
        }

        public void Update()
        {
            int i = 0, sum_i = 0;
            foreach (var person in table.info.LoopWorkPersons())
            {
                thumb_sum[sum_i] = 0;
                foreach (var workno in table.LoopWorkNo())
                    thumb_sum[sum_i] += thumb[i++] = table.WorkCount(workno, person);
                sum_i++;
            }

            var ix = 0;
            for (i = 0; i < table.work_count; i++)
                for (var j = i+1; j < table.work_count; j++)
                    thumb_repeat[ix++] = _ReadRepeatCount(i, j);
        }
        public int ReadSum(string person)
        {
            var ix = Array.IndexOf(table.info.work_person_map, person);
            if (ix == -1) throw new ArgumentException("person not found");
            return thumb_sum[ix];
        }
        public int Read(string person, int workno)
        {
            var ix = Array.IndexOf(table.info.work_person_map, person);
            if (ix == -1) throw new ArgumentException("person not found");
            return thumb[ix * table.work_count + workno];
        }
        public bool HasNoRepeat()
        {
            return thumb_repeat.Contains(0);
        }
        internal int ReadRepeatCount(int workno, int bijiao_workno)
        {
            if (workno == bijiao_workno) throw new ArgumentException();
            var a = workno;
            var b = bijiao_workno;
            if (a < bijiao_workno)
            {
                a = bijiao_workno;
                b = workno;
            }
            var ix = table.work_count - workno;
            ix = ((ix-- * ix) >> 1) +b- a - 1;
            return thumb_repeat[ix];
        }
        internal int _ReadRepeatCount(int workno, int bijiao_workno)
        {
            var a = table.ReadPersonByWorkNo(workno).GetEnumerator();
            var b = table.ReadPersonByWorkNo(bijiao_workno).GetEnumerator();

            var same = 0;
            while (a.MoveNext() && b.MoveNext())
                if (a.Current == b.Current) same++;

            return same;
        }

        public void Print()
        {
            int i = 0;
            foreach (var person in table.info.LoopWorkPersons())
            {
                foreach (var workno in table.LoopWorkNo())
                    Console.Write($"{thumb[i++]}    ");
                Console.WriteLine();
            }
        }
        public void SaveCSV(string csv_name)
        {
            using (var file = File.Create($"./{csv_name}.csv"))
            {
                var writer = new StreamWriter(file);

                int i = 0, sum_i = 0;
                foreach (var person in table.info.LoopWorkPersons())
                {
                    foreach (var workno in table.LoopWorkNo())
                        writer.Write($"{thumb[i++]},");
                    writer.Write($"{thumb_sum[sum_i++]},");
                    writer.WriteLine();
                }
                writer.Flush();
            }
        }
        public void FillExcelSheet(Excel2003Sheet pb)
        {
            var rowno = 1;
            var row = pb.ToRow(rowno);
            row.ToCell(1).SetValue("姓名");
            foreach (var workno in table.LoopWorkNo()) row.ToCell(1 + workno + 1).SetValue($"任务 {workno + 1}");
            row.ToCell(2 + table.work_count).SetValue("总计");

            int i = 0, sum_i = 0;
            foreach (var person in table.info.LoopWorkPersons())
            {
                rowno++;
                row = pb.ToRow(rowno);
                row.ToCell(1).SetValue(person);
                foreach (var workno in table.LoopWorkNo()) row.ToCell(1 + workno + 1).SetValue(thumb[i++]);
                row.ToCell(2 + table.work_count).SetValue(thumb_sum[sum_i++]);
            }

            rowno++;

            rowno++;
            row = pb.ToRow(rowno);
            row.ToCell(1).SetValue($"重复对比");
            for (i = 1; i < table.work_count; i++)
                row.ToCell(1+i).SetValue($"任务 {i+1}");

            int ix = 0;
            for (i = 1; i < table.work_count; i++)
            {
                rowno++;
                row = pb.ToRow(rowno);
                row.ToCell(1).SetValue($"任务 {i}");
                for (var j = i; j < table.work_count; j++) row.ToCell(1 + j).SetValue(thumb_repeat[ix++]);
            }
        }
        public void SaveExcel(string name)
        {
            var xls = new Excel2003File();
            var pb = xls.GetWorkbook().ToSheet("缩略图");
            FillExcelSheet(pb);
            using (var f = File.Create($"./{name}.xls")) xls.ToStream(f);
        }
    }
}
